﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.ComponentModel;

namespace EasyProp.Tests
{
    [TestFixture]
    public class EasyPropBuilderFixture
    {
        [Test]
        public void should_build_with_constructor_parameters()
        {
            EasyPropBuilder builder = new EasyPropBuilder();
            ClassWithNonEmptyConstructor theObject = builder.Build<ClassWithNonEmptyConstructor>("Foo", 3);
            Assert.AreEqual("Foo", theObject.Foo);
            Assert.AreEqual(3, theObject.Bar);
        }

        [Test]
        public void should_chain_filters_in_inheritance_hierarchy_in_top_down_order()
        {
            List<IPropertySetterFilter> filterChain =
                EasyPropBuilder.CreateFilterChain<AfterPropertySetFilterAttribute>(typeof(ClassB));

            Assert.AreEqual(typeof(DoNothingFilter), filterChain[0].GetType());
            Assert.AreEqual(typeof(MarkObjectAsDirty), filterChain[1].GetType());
            Assert.AreEqual(typeof(CountInvocationsFilter), filterChain[2].GetType());
            Assert.AreEqual(typeof(NotifyPropertyChanged), filterChain[3].GetType());
        }

        [AfterPropertySetFilter(typeof(DoNothingFilter))]
        [AfterPropertySetFilter(typeof(MarkObjectAsDirty))]
        public abstract class ClassA
        {
            public virtual string MyProperty { get; set; }
            public virtual bool IsDirty { get; set; }
        }

        [AfterPropertySetFilter(typeof(CountInvocationsFilter))]
        [AfterPropertySetFilter(typeof(NotifyPropertyChanged))]
        public class ClassB : ClassA
        {
        }

        [BeforePropertySetFilter(typeof(DoNothingFilter))]
        public class ClassWithNonEmptyConstructor
        {
            public ClassWithNonEmptyConstructor(string foo, int bar)
            {
                Foo = foo; Bar = bar;
            }

            public readonly string Foo;
            public readonly int Bar;
        }
    }

}
